#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
核反应堆两流体子通道分析程序的主入口

该模块提供了程序的主要执行流程，包括：
1. 配置文件解析
2. 日志系统设置
3. 模型初始化
4. 仿真执行
5. 结果输出
"""

import os
import sys
import json
import logging
import argparse
from datetime import datetime

# 修改为绝对导入
from nuclear_subchannel.physics.two_fluid_model import TwoFluidModel
from nuclear_subchannel.physics.fluid_properties import FluidProperties
from nuclear_subchannel.physics.heat_conduction import HeatConductionSolver
from nuclear_subchannel.utils.output_processor import OutputProcessor

def setup_logging(output_dir: str, log_level: str = 'INFO') -> None:
    """
    设置日志系统
    
    参数:
        output_dir: 输出目录
        log_level: 日志级别
    """
    # 创建输出目录
    os.makedirs(output_dir, exist_ok=True)
    
    # 设置日志格式
    log_format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    logging.basicConfig(
        level=getattr(logging, log_level),
        format=log_format,
        handlers=[
            logging.FileHandler(os.path.join(output_dir, 'simulation.log')),
            logging.StreamHandler()
        ]
    )

def load_config(config_file: str) -> dict:
    """
    加载配置文件
    
    参数:
        config_file: 配置文件路径
        
    返回:
        配置字典
    """
    with open(config_file, 'r', encoding='utf-8') as f:
        config = json.load(f)
    
    # 验证必要的配置项
    required_fields = [
        'geometry', 'operating_conditions', 
        'numerical_parameters', 'output_control'
    ]
    
    for field in required_fields:
        if field not in config:
            raise ValueError(f"配置文件缺少必要的{field}字段")
            
    return config

def initialize_simulation(config: dict) -> tuple:
    """
    初始化仿真模型
    
    参数:
        config: 配置字典
        
    返回:
        (两流体模型, 导热求解器, 输出处理器)
    """
    # 初始化流体物性计算器
    fluid_props = FluidProperties()
    
    # 初始化两流体模型
    model = TwoFluidModel(
        n_axial=config['geometry']['n_axial'],
        n_channels=config['geometry']['n_channels'],
        channel_length=config['geometry']['channel_length'],
        channel_area=config['geometry']['channel_area'],
        fluid_properties=fluid_props
    )
    
    # 初始化导热求解器
    heat_solver = HeatConductionSolver(
        n_axial=config['geometry']['n_axial'],
        n_radial=config['geometry']['n_radial'],
        rod_diameter=config['geometry']['rod_diameter'],
        material_props=config['material_properties']
    )
    
    # 初始化输出处理器
    output_processor = OutputProcessor(
        output_dir=config['output_control']['output_dir'],
        save_frequency=config['output_control']['save_frequency']
    )
    
    return model, heat_solver, output_processor

def run_simulation(model: TwoFluidModel, 
                  heat_solver: HeatConductionSolver,
                  output_processor: OutputProcessor,
                  config: dict) -> None:
    """
    执行仿真计算
    
    参数:
        model: 两流体模型
        heat_solver: 导热求解器
        output_processor: 输出处理器
        config: 配置字典
    """
    # 设置初始条件
    model.initialize(config['initial_conditions'])
    
    # 获取数值参数
    dt = config['numerical_parameters']['time_step']
    max_time = config['numerical_parameters']['max_time']
    
    # 时间推进循环
    current_time = 0.0
    while current_time < max_time:
        # 求解导热方程
        q_wall = heat_solver.solve(model.temp_f)
        
        # 更新两流体模型
        model.solve(dt, q_wall)
        
        # 保存结果
        output_processor.save_timestep(current_time, model, heat_solver)
        
        current_time += dt
        
    # 生成最终报告
    output_processor.generate_report()

def main():
    """主函数"""
    # 解析命令行参数
    parser = argparse.ArgumentParser(description='核反应堆两流体子通道分析程序')
    parser.add_argument('--config', required=True, help='配置文件路径')
    parser.add_argument('--output', required=True, help='输出目录')
    parser.add_argument('--log-level', default='INFO', help='日志级别')
    args = parser.parse_args()
    
    try:
        # 设置日志系统
        setup_logging(args.output, args.log_level)
        logger = logging.getLogger(__name__)
        
        # 记录开始时间
        start_time = datetime.now()
        logger.info(f"仿真开始于 {start_time}")
        
        # 加载配置
        config = load_config(args.config)
        logger.info("成功加载配置文件")
        
        # 初始化仿真
        model, heat_solver, output_processor = initialize_simulation(config)
        logger.info("成功初始化仿真模型")
        
        # 执行仿真
        run_simulation(model, heat_solver, output_processor, config)
        
        # 记录结束时间
        end_time = datetime.now()
        duration = end_time - start_time
        logger.info(f"仿真结束于 {end_time}")
        logger.info(f"总耗时: {duration}")
        
    except Exception as e:
        logger.error(f"仿真过程中发生错误: {str(e)}", exc_info=True)
        sys.exit(1)

if __name__ == '__main__':
    main() 